Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

156
Vistas
llamadas de función de "prefijo" por llamada de función específica

Tengo un código JavaScript que consta de varias funciones que pueden o no llamarse entre sí. Aquí hay un ejemplo:

 function a(x) { return 2*x; } function b(x, y) { return a(y) + x; } function c() { return b(1, 2); }

Tengo una función especial que toma una función y sus argumentos y devuelve el valor calculado (entre otras cosas, vea la explicación a continuación):

 function pre(f, ...args) { return f(...args); }

¿Es posible "prefijar" todas las llamadas de función con esta función SIN necesidad de modificar/reasignar las funciones?

Es decir, la llamada pre(c); debería comportarse como si las funciones estuvieran definidas así:

 function a(x) { return 2*x; } function b(x, y) { return pre(a, y) + x; } function c() { return pre(b, 1, 2); }
  • ¿Tal vez podamos definir un objeto que anule el comportamiento de llamada de función "estándar", de modo que intercepte la llamada y la prefije con esta función?
  • Si esto requiere la presencia de ciertos objetos, o que todas las funciones sean miembros de un determinado objeto, está bien.
  • Si esto requiere que una llamada de función se escriba de manera diferente (no solo c(); ), está bien.

Caso de uso:

Tengo un programa (Java) en el que un usuario final puede definir funciones de JavaScript. Este programa lee algunos datos externos y llama a estas funciones de JavaScript. Finalmente, algunos resultados de estas llamadas a funciones se devolverán al usuario final.

Las funciones definidas por el usuario no tienen efectos secundarios (el programa se asegura de eso); son puras funciones de cálculo. Por eso, basta con llamar a cada función casi una vez: siempre darán el mismo resultado para una entrada idéntica. Así que quería implementar un mecanismo de almacenamiento en caché dentro de pre como, por ejemplo, este:

 var cache = new Map(); function pre(f, ...args) { var array = new Array(args.length + 1); array[0] = f.name; for (var i = 0; i < args.length; i++) { array[i+1] = args[i]; } var stringified = JSON.stringify(array); if (cache.has(stringified)) { return cache.get(stringified); } else { var calc = Object.freeze(f(...args)); cache.set(stringified, calc); return calc; } }

Actualmente lo implementé para que solo modifique todas las funciones definidas por el usuario (que se dan como cadenas, por lo que manipulo cadenas) para contener la llamada pre . Pero estoy interesado en una solución más elegante, una solución que no requiera modificación de código, y si la hay, estoy seguro de que el conocimiento de esa solución puede ayudar en muchas situaciones.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Si te entiendo correctamente, quieres poder definir funciones como esta:

 function a(x) { return 2*x; } function b(x, y) { return a(y) + x; } function c() { return b(1, 2); }

y luego, después de definirlas (después de que existan las funciones y los enlaces a , b y c para ellas), intercepte todas las llamadas a a , b o c (incluidas las que están dentro de b y c ) sin reasignar a , b , c identificadores (más formalmente, enlaces ).

No puedes hacer eso. Requeriría llegar a b (por ejemplo) y cambiar qué a usa b para encontrar y llamar a la función asignada a a . Puede cambiar el valor del enlace a que utiliza b (p. ej., a qué función se refiere a ) reasignándolo, pero no puede cambiar a enlace que utiliza b .

Solo por el bien de cualquier acechador que quiera saber cómo hacerlo con la reasignación, así es como, pero el OP ha dicho específicamente que no quieren hacer esto:

 var cache = new Map(); function pre(f, ...args) { var array = new Array(args.length + 1); array[0] = f.name; for (var i = 0; i < args.length; i++) { array[i+1] = args[i]; } var stringified = JSON.stringify(array); if (cache.has(stringified)) { return cache.get(stringified); } else { var calc = Object.freeze(f(...args)); cache.set(stringified, calc); return calc; } } // Doesn't handle `this` because the OP didn't need to and the // `pre` function would have to be modified to handle it function wrap(original) { return (...args) => pre(original, ...args); } function a(x) { console.log(`a called with`, x); return 2 * x; } function b(x, y) { console.log(`b called with`, x, y); return a(y) + x; } function c() { console.log(`c called`); return b(1, 2); } a = wrap(a); b = wrap(b); c = wrap(c); console.log(`First call:`); console.log(c()); console.log(`Second call:`); console.log(c());


En un comentario has dicho:

Más precisamente, quiero saber si hay un nivel entre "lo que hace b(1, 2)" (la función en sí) y la... cosa... (¿el intérprete?) que dice "ahora llama a esa función" . Y si hay un nivel intermedio, quiero saber si eso se puede modificar.

El único nivel intermedio en un entorno de JavaScript estándar es el objeto de entorno léxico que contiene los enlaces a , b y c , que es lo que estaríamos cambiando al reasignarlos. No hay nada más que podamos hacer para interceptar/ajustar esas llamadas a funciones.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda